package com.xxmw.transaction.service.job.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxmw.transaction.common.entity.P;
import com.xxmw.transaction.common.utils.Constant;
import com.xxmw.transaction.conf.job.AbstractSchedule;
import com.xxmw.transaction.mapper.ScheduleJobMapper;
import com.xxmw.transaction.model.ScheduleJob;
import com.xxmw.transaction.service.job.ScheduleJobService;
import org.apache.commons.lang.StringUtils;
import org.quartz.CronTrigger;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * 任务job业务接口实现类
 *
 * @author xiangzuotao
 * @date 2018年7月25日
 */
@Service("scheduleJobService")
public class ScheduleJobServiceImpl extends ServiceImpl<ScheduleJobMapper, ScheduleJob> implements ScheduleJobService {

    @Autowired
    private Scheduler scheduler;

    @PostConstruct
    public void init() {
        List<ScheduleJob> jobList = list();
        jobList.forEach(job -> {
            CronTrigger cronTrigger = AbstractSchedule.getCronTrigger(scheduler, job.getJobId());
            if (cronTrigger == null) {
                AbstractSchedule.create(scheduler, job);
            } else {
                AbstractSchedule.update(scheduler, job);
            }
        });
    }

    @Override
    public P<ScheduleJob> getJobList(Integer pageNum, Integer pageSize, Integer type, Integer bourse, String beanName) {
        IPage<ScheduleJob> page = new Page<>(pageNum, pageSize);
        QueryWrapper<ScheduleJob> q = new QueryWrapper<>();
        q.eq(StringUtils.isNotBlank(beanName), "bean_name", beanName);
        q.eq(null != type, "type", type);
        q.eq(null != bourse, "bourse", bourse);
        page(page, q);
        return new P<>(page.getTotal(), page.getRecords());
    }

    @Override
    public ScheduleJob getScheduleJob(Long jobId) {
        return getById(jobId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addOrUpdate(ScheduleJob scheduleJob) {
        if (scheduleJob.getJobId() == null) {
            save(scheduleJob);
            AbstractSchedule.create(scheduler, scheduleJob);
        } else {
            updateById(scheduleJob);
            AbstractSchedule.update(scheduler, scheduleJob);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(Long[] jobIds) {
        for (Long jobId : jobIds) {
            removeById(jobId);
            AbstractSchedule.deleteJob(scheduler, jobId);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void upateBatch(Long[] jobIds, int status) {
        for (Long jobId : jobIds) {
            ScheduleJob scheduleJob = getById(jobId);
            if (scheduleJob != null) scheduleJob.setStatus(status);
            updateById(scheduleJob);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void run(Long[] jobIds) {
        for (Long jobId : jobIds) {
            ScheduleJob scheduleJob = getById(jobId);
            if (scheduleJob != null) AbstractSchedule.run(scheduler, scheduleJob);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pause(Long[] jobIds) {
        for (Long jobId : jobIds) {
            AbstractSchedule.pauseJob(scheduler, jobId);
        }
        upateBatch(jobIds, Constant.ScheduleStatus.PAUSE.getValue());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resume(Long[] jobIds) {
        for (Long jobId : jobIds) {
            AbstractSchedule.resumeJob(scheduler, jobId);
        }
        upateBatch(jobIds, Constant.ScheduleStatus.NORMAL.getValue());
    }

    @Override
    public ScheduleJob getByBourseAndSymbol(Integer bourse, String symbol) {
        QueryWrapper<ScheduleJob> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("bourse", bourse);
        queryWrapper.eq("symbol", symbol);
        return getOne(queryWrapper);
    }

}
